//#ifdef __USE_CMSIS
#include "LPC17xx.h"
//#endif
//#include <stdio.h>
#include "sysinfo.h"

// http://knowledgebase.nxp.com/showthread.php?t=2106

// Voir
void PLL0Setup(void)
{
// CLOCK
  UART2_PrintString("*CLOCK SETUP\n");
  LPC_SC->SCS &= ~bit5;
	if (LPC_SC->SCS & (1 << 5))
    {   // If Main Oscillator is enabled
		UART2_PrintString("*WAIT MAIN OSC UP...\n");
	    while ((LPC_SC->SCS & (1<<6)) == 0);  // Wait for Oscillator to be ready
	}
	UART2_PrintString("*CLOCK DIVIDER\n");
	LPC_SC->CCLKCFG   = 3;      // Setup Clock Divider
	//LPC_SC->PCLKSEL0  = PCLKSEL0_Val;     // Peripheral Clock Selection
	//LPC_SC->PCLKSEL1  = PCLKSEL1_Val;
	UART2_PrintString("*CLOCK SOURCE\n");
	LPC_SC->CLKSRCSEL = 0;    // Select Clock Source for PLL0

  // PLL0
  UART2_PrintString("*PLL0 SETUP\n");
  LPC_SC->PLL0CFG   = 0x23; // PLL0CFG_Val;      /* configure PLL0                     */
  LPC_SC->PLL0FEED  = 0xAA;
  LPC_SC->PLL0FEED  = 0x55;

  LPC_SC->PLL0CON   = 0x01;             /* PLL0 Enable                        */
  LPC_SC->PLL0FEED  = 0xAA;
  LPC_SC->PLL0FEED  = 0x55;
  UART2_PrintString("*WAIT FOR PLOCK0...\n");
  while (!(LPC_SC->PLL0STAT & (1<<26)));/* Wait for PLOCK0                    */

  LPC_SC->PLL0CON   = 0x03;             /* PLL0 Enable & Connect              */
  LPC_SC->PLL0FEED  = 0xAA;
  LPC_SC->PLL0FEED  = 0x55;
  UART2_PrintString("*WAIT FOR PLLC0_STAT & PLLE0_STAT...\n");
  while (!(LPC_SC->PLL0STAT & ((1<<25) | (1<<24))));/* Wait for PLLC0_STAT & PLLE0_STAT */

	UART2_PrintString("*DONE, EXITING.\n");
 return;
}

void PLL0SetupFull(void)
{
	int i;
// PLL0 setup sequence, the following sequence must be followed step by step in order to have PLL0 initialized and running:
// 1. DISCONNECT PLL0 (bit1 PLLC0) with one feed sequence if PLL0 is already connected.
	// A correct feed sequence must be written to the PLL0FEED register in order for changes to
	// the PLL0CON and PLL0CFG registers to take effect. The feed sequence is:
	// 1. Write the value 0xAA to PLL0FEED.
	// 2. Write the value 0x55 to PLL0FEED.
    UART2_PrintString("*DISCONNETING...\n");
	LPC_SC->PLL0CON &= ~bit1; // Clear bit 1
	 LPC_SC->PLL0FEED = 0xAA; // Feed
	 LPC_SC->PLL0FEED = 0x55;
    UART2_PrintString("*DISCONNETED\n");
// 2. DISABLE PLL0 (bit0 PLLE0) with one feed sequence.
    UART2_PrintString("*DISABLING...\n");
	 LPC_SC->PLL0CON &= ~bit0; // Clear bit 0
	  LPC_SC->PLL0FEED = 0xAA; // Feed
	  LPC_SC->PLL0FEED = 0x55;
	UART2_PrintString("*DISABLED\n");
// 3. Change the CPU Clock Divider setting to SPEED UP OPERATION without PLL0, if desired.
	 //LPC_SC->CCLKCFG = 0;  // Division par 1 -> vitesse Maxi ?? Quelle CLock utilisee alors ??
// 4. Write to the Clock Source Selection Control register to change the clock source if needed.
	UART2_PrintString("*SOURCE\n");
	 LPC_SC->CLKSRCSEL = 0x01; // 1 = quartz
// 5. Write to the PLL0CFG and make it effective with one feed sequence. The PLL0CFG can only be updated when PLL0 is disabled.
//	 Ici on doit donner le Multiplier et PreDivider
	UART2_PrintString("*PLL0CFG\n");
	 LPC_SC->PLL0CFG = 0x23; // 60 MHz
// 6. ENABLE PLL0 with one feed sequence.
    UART2_PrintString("*ENABLING...\n");
	 LPC_SC->PLL0CON |= bit0; // Set bit 0
// 7. Change the CPU Clock Divider setting for the operation with PLL0. It is critical to do this before connecting PLL0.
	 LPC_SC->CCLKCFG = 3;  // Division par 3
// 8. Wait for PLL0 to achieve lock by monitoring the PLOCK0 bit (bit26) in the PLL0STAT register,
// or using the PLOCK0 interrupt, or wait for a fixed time when the input clock to PLL0 is
// slow (i.e. 32 kHz). The value of PLOCK0 may not be stable when the PLL reference
// frequency (FREF, the frequency of REFCLK, which is equal to the PLL input
// frequency divided by the pre-divider value) is less than 100 kHz or greater than
// 20 MHz. In these cases, the PLL may be assumed to be stable after a start-up time
// has passed. This time is 500 μs when FREF is greater than 400 kHz and 200 / FREF
// seconds when FREF is less than 400 kHz.
	UART2_PrintString("*WAITING\n");

	 for(i=0; i<10000000; i++);

	// while( (LPC_SC->PLL0STAT & bit26) != 1 )
		//printf("Waiting PLL0 locking...\n");
		 ;
     //printf("PLL0 locked, connecting...\n");
// 9. Connect PLL0 with one feed sequence.
	 UART2_PrintString("*CONNECTING\n");
  	 LPC_SC->PLL0CON |= bit1; // Set bit 1
	  LPC_SC->PLL0FEED = 0xAA; // Feed
	  LPC_SC->PLL0FEED = 0x55;
}
void PLL0SetupRTC(void)
{
	int i;
// PLL0 setup sequence, the following sequence must be followed step by step in order to have PLL0 initialized and running:
// 1. DISCONNECT PLL0 (bit1 PLLC0) with one feed sequence if PLL0 is already connected.
	// A correct feed sequence must be written to the PLL0FEED register in order for changes to
	// the PLL0CON and PLL0CFG registers to take effect. The feed sequence is:
	// 1. Write the value 0xAA to PLL0FEED.
	// 2. Write the value 0x55 to PLL0FEED.
	LPC_SC->PLL0CON &= ~bit1; // Clear bit 1
	 LPC_SC->PLL0FEED = 0xAA; // Feed
	 LPC_SC->PLL0FEED = 0x55;
// 2. DISABLE PLL0 (bit0 PLLE0) with one feed sequence.
	 LPC_SC->PLL0CON &= ~bit0; // Clear bit 0
	  LPC_SC->PLL0FEED = 0xAA; // Feed
	  LPC_SC->PLL0FEED = 0x55;
// 3. Change the CPU Clock Divider setting to SPEED UP OPERATION without PLL0, if desired.
	 LPC_SC->CCLKCFG = 0;  // Division par 1 -> vitesse Maxi ?? Quelle CLock utilisee alors ??
// 4. Write to the Clock Source Selection Control register to change the clock source if needed.
	 LPC_SC->CLKSRCSEL = 0x02; // utilise RTC 32768 kHz
// 5. Write to the PLL0CFG and make it effective with one feed sequence. The PLL0CFG can only be updated when PLL0 is disabled.
//	 Ici on doit donner le Multiplier et PreDivider
	 LPC_SC->PLL0CFG = 0x12254; // p.45 Exemple pour 72 MHz avec la RTC
// 6. ENABLE PLL0 with one feed sequence.
	 LPC_SC->PLL0CON |= bit0; // Set bit 0
// 7. Change the CPU Clock Divider setting for the operation with PLL0. It is critical to do this before connecting PLL0.
	 LPC_SC->CCLKCFG = 63;  // Division par 64 (63+1)
// 8. Wait for PLL0 to achieve lock by monitoring the PLOCK0 bit (bit26) in the PLL0STAT register,
// or using the PLOCK0 interrupt, or wait for a fixed time when the input clock to PLL0 is
// slow (i.e. 32 kHz). The value of PLOCK0 may not be stable when the PLL reference
// frequency (FREF, the frequency of REFCLK, which is equal to the PLL input
// frequency divided by the pre-divider value) is less than 100 kHz or greater than
// 20 MHz. In these cases, the PLL may be assumed to be stable after a start-up time
// has passed. This time is 500 μs when FREF is greater than 400 kHz and 200 / FREF
// seconds when FREF is less than 400 kHz.


	 for(i=0; i<10000; i++);

	 while( (LPC_SC->PLL0STAT & bit26) != 1 )
		//printf("Waiting PLL0 locking...\n");
		 ;
     //printf("PLL0 locked, connecting...\n");
// 9. Connect PLL0 with one feed sequence.
  	 LPC_SC->PLL0CON |= bit1; // Set bit 1
	  LPC_SC->PLL0FEED = 0xAA; // Feed
	  LPC_SC->PLL0FEED = 0x55;
}
